#include<iostream>
#include<string>
#include<list>
#include "sv_node.hpp"
#include "my570list.hpp"
#include "cs570.h"

using namespace std;

extern char* HomeDir1;
extern pthread_mutex_t PermList_lock;

My570List* kwrdList = new My570List();
My570List* nameList = new My570List();
My570List* sha1List = new My570List();
My570List* nonceList = new My570List();
My570List* fileidList = new My570List();

unsigned char tohex(unsigned char ch){

	switch(ch)
	{
		case '0': return 0x00;
		case '1': return 0x01;
		case '2': return 0x02;
		case '3': return 0x03;
		case '4': return 0x04;
		case '5': return 0x05;
		case '6': return 0x06;
		case '7': return 0x07;
		case '8': return 0x08;
		case '9': return 0x09;
		case 'a': return 0x0a;
		case 'b': return 0x0b;
		case 'c': return 0x0c;
		case 'd': return 0x0d;
		case 'e': return 0x0e;
		case 'f': return 0x0f;
	}

	return 0x00;

}



/*class Boot_Elem
{
	public:
		Boot_Elem();
	    int index;
		char* FileName;
		char* Key;
		unsigned char* Sha1;
};*/



Boot_Elem :: Boot_Elem()
{
	index=0;
	FileName=NULL;
	Key=NULL;
	Sha1=NULL;
	Nonce=NULL;
	password=0;
}


void Boot_Load()
{
	string NodeHome = (string(HomeDir1)).substr(0,(int)strlen(HomeDir1)-1);
	//string NodeHome = "/home/scf-03/kavuluru/cs551/homework4_final/test";
	string kwrdFile = NodeHome + "/kwrd_index";
	string nameFile = NodeHome + "/name_index";
	string sha1File = NodeHome + "/sha1_index";
	string nonceFile = NodeHome + "/nonce_index";
	string fileidFile = NodeHome + "/fileid_index";

	FILE *kwrd = fopen(kwrdFile.c_str(),"r");
	if(kwrd!=NULL)
	{
		while(!feof(kwrd)){

			Boot_Elem *belem = new Boot_Elem();
			//char* keyarr = new char[300];
			//---------------------- change -------------------//
			belem->Key = (unsigned char*)malloc(128);
			char* keyarr=(char*)malloc(257);

			unsigned char* hexstring1 = (unsigned char*)malloc(128);
			unsigned char temp3;
            unsigned char temp4;
 

            //---------------------- change ------------------//
			int i=0;
			fscanf(kwrd,"%d %s\n",&i,keyarr);
			if(i==0){break;}
			belem->index = i;
			//---------------------change1-------------------//

			int ik1=0;
			for(int i=0;i<256;i=i+2)
			{
				temp3=tohex(keyarr[i]);
				temp4=tohex(keyarr[i+1]);

				temp3=temp3<<4;

				hexstring1[ik1]=temp3 | temp4;
				ik1=ik1+1;
				
			}
			memcpy(belem->Key,hexstring1,128);
			//---------------------change1-------------------//
			//belem->Key = new char[strlen(keyarr)];
			//strcpy(belem->Key,(string(keyarr)).c_str());

            kwrdList->Append((void*)belem);
			/*cout<<"i ->"<<i<<endl;
			cout<<"key ->"<<keyarr<<endl;*/
		}
		
	}
	fclose(kwrd);

	FILE *name = fopen(nameFile.c_str(),"r");
	if(name!=NULL)
	{
		
		while(!feof(name)){
			Boot_Elem *belem = new Boot_Elem;
			belem->FileName = (char*)malloc(100);
			char* namearr = new char[100];
			int i=0;
			fscanf(name,"%d %s",&i,namearr);
			if(i==0){break;}
			belem->index=i;
			strcpy(belem->FileName,(string(namearr)).c_str());
            
            nameList->Append((void*)belem);
		}
	}
	fclose(name);

    FILE *sha1 = fopen(sha1File.c_str(),"r");
	if(sha1!=NULL)
	{		
		  while(!feof(sha1)){ 
		    
			Boot_Elem* belem = new Boot_Elem();
			belem->Sha1 = (unsigned char*)malloc(20);
			char* sha1arr=(char*)malloc(41);

			unsigned char* hexstring = (unsigned char*)malloc(20);
			unsigned char temp1;
            unsigned char temp2;

			int i=0;
			fscanf(sha1,"%d %s\n",&i,sha1arr);
			//cout<<"i ->"<<i<<endl;
			belem->index=i;
			//cout<<"key ->"<<sha1arr<<endl;
			if(i==0){break;}  
			int ik=0;
			for(int i=0;i<40;i=i+2)
			{
				temp1=tohex(sha1arr[i]);
				temp2=tohex(sha1arr[i+1]);

				temp1=temp1<<4;

				hexstring[ik]=temp1 | temp2;
				ik=ik+1;
				
			}
              
			  memcpy(belem->Sha1,hexstring,20);
			  sha1List->Append((void*)belem);

			  free(sha1arr);
			  free(hexstring);
		}//while
	}
	fclose(sha1);

	FILE *nonce = fopen(nonceFile.c_str(),"r");
	if(nonce!=NULL){
		  while(!feof(nonce)){ 
			Boot_Elem* belem = new Boot_Elem();
			belem->Nonce = (unsigned char*)malloc(20);
			char* noncearr=(char*)malloc(41);

			unsigned char* hexstring2 = (unsigned char*)malloc(20);
			unsigned char ch1;
            unsigned char ch2;

			int i=0;
			int pwd=0;
			fscanf(nonce,"%d %s %d\n",&i,noncearr,&pwd);
			belem->index=i;
            belem->password=pwd; 

			if(i==0){break;}  
			int ij=0;
			for(int i=0;i<40;i=i+2)
			{
				ch1=tohex(noncearr[i]);
				ch2=tohex(noncearr[i+1]);

				ch1=ch1<<4;

				hexstring2[ij]=ch1 | ch2;
				ij=ij+1;
				
			}
              
			  memcpy(belem->Nonce,hexstring2,20);
			  nonceList->Append((void*)belem);

			  free(noncearr);
			  free(hexstring2);

		  }//while
	}
	fclose(nonce);

	FILE *fileid = fopen(fileidFile.c_str(),"r");
	if(fileid!=NULL){
        while(!feof(fileid)){
			Boot_Elem* belem = new Boot_Elem();
			belem->FileId = (unsigned char*)malloc(20);
			char* fileidarr=(char*)malloc(41);

			unsigned char* hexstringfd = (unsigned char*)malloc(20);
			unsigned char temp1fd;
            unsigned char temp2fd;

			int i=0;
			fscanf(fileid,"%d %s\n",&i,fileidarr);
			//cout<<"i ->"<<i<<endl;
			belem->index=i;
			//cout<<"key ->"<<sha1arr<<endl;
			if(i==0){break;}  
			int ik=0;
			for(int i=0;i<40;i=i+2)
			{
				temp1fd=tohex(fileidarr[i]);
				temp2fd=tohex(fileidarr[i+1]);

				temp1fd=temp1fd<<4;

				hexstringfd[ik]=temp1fd | temp2fd;
				ik=ik+1;
				
			}
              
			  memcpy(belem->FileId,hexstringfd,20);
			  fileidList->Append((void*)belem);

			  free(fileidarr);
			  free(hexstringfd);

		}//while
	}//if fileid is not null
	fclose(fileid);

	return;

}

void Boot_Write()
{
    string NodeHome = (string(HomeDir1)).substr(0,(int)strlen(HomeDir1)-1);
	//string NodeHome = "/home/scf-03/kavuluru/cs551/homework4_final/test";
	string kwrdFile = NodeHome + "/kwrd_index";
	string nameFile = NodeHome + "/name_index";
	string sha1File = NodeHome + "/sha1_index";
	string nonceFile = NodeHome + "/nonce_index";
	string fileidFile = NodeHome + "/fileid_index";

    FILE* kwrd = fopen(kwrdFile.c_str(),"w");   
	if(kwrdList->Length()!=0){
	My570ListElem *kelem = new My570ListElem();
	for(kelem=kwrdList->First();kelem!=NULL;kelem=kwrdList->Next(kelem))
	{
		fprintf(kwrd,"%d ",((Boot_Elem*)(kelem->Obj()))->index);//%s\n",((Boot_Elem*)(kelem->Obj()))->index,((Boot_Elem*)(kelem->Obj()))->Key);
		for(int i2=0;i2<128;i2++)
		{
			fprintf(kwrd,"%02x",((Boot_Elem*)(kelem->Obj()))->Key[i2]);
		}
		fprintf(kwrd,"\n");
	}
	}
	fclose(kwrd);
	

	FILE* name = fopen(nameFile.c_str(),"w");
	if(nameList->Length()!=0){
	My570ListElem *nelem = new My570ListElem();
    for(nelem=nameList->First();nelem!=NULL;nelem=nameList->Next(nelem))
	{
		fprintf(name,"%d %s\n",((Boot_Elem*)(nelem->Obj()))->index,((Boot_Elem*)(nelem->Obj()))->FileName);
	}
	}
	fclose(name);
	
	FILE* sha1 = fopen(sha1File.c_str(),"w");
	if(sha1List->Length()!=0){
	My570ListElem *selem = new My570ListElem();
    for(selem=sha1List->First();selem!=NULL;selem=sha1List->Next(selem))
	{
		fprintf(sha1,"%d ",((Boot_Elem*)(selem->Obj()))->index);
		for(int i1=0;i1<20;i1++)
		{
			fprintf(sha1,"%02x",((Boot_Elem*)(selem->Obj()))->Sha1[i1]);
		}
		fprintf(sha1,"\n");
	}
	}
	fclose(sha1);

    FILE* nonce = fopen(nonceFile.c_str(),"w");
	if(nonceList->Length()!=0){    
	My570ListElem *olem = new My570ListElem();
	for(olem=nonceList->First();olem!=NULL;olem=nonceList->Next(olem))
	{
		fprintf(nonce,"%d ",((Boot_Elem*)(olem->Obj()))->index);
		for(int i1=0;i1<20;i1++)
		{
			fprintf(nonce,"%02x",((Boot_Elem*)(olem->Obj()))->Nonce[i1]);
		}
		fprintf(nonce," %d\n",((Boot_Elem*)(olem->Obj()))->password);

		//fprintf(nonce,"\n");
	}
	}
	fclose(nonce);

	FILE* fileid = fopen(fileidFile.c_str(),"w");
	if(fileidList->Length()!=0){
    My570ListElem *felem = new My570ListElem();
	for(felem=fileidList->First();felem!=NULL;felem=fileidList->Next(felem))
	{
		fprintf(fileid,"%d ",((Boot_Elem*)(felem->Obj()))->index);
		for(int i2=0;i2<20;i2++)
		{
		fprintf(fileid,"%02x",((Boot_Elem*)(felem->Obj()))->FileId[i2]);
		}
		fprintf(fileid,"\n");
	}
	}
	fclose(fileid);

		
	return;
}

/*
int main()
{
  Boot_Load();
  

  My570ListElem *elem = new My570ListElem();

  for(elem=kwrdList->First();elem!=NULL;elem=kwrdList->Next(elem))
	{
	  string check=string(((Boot_Elem*)(elem->Obj()))->Key);

	  if(check.compare("getto")==0){
		  cout<<"llllllllllllllllllllllll"<<endl;
	  cout<<((Boot_Elem*)(elem->Obj()))->index<<endl;
	  cout<<((Boot_Elem*)(elem->Obj()))->Key<<endl;
	  }
	}

  Boot_Write();
  return 0;

}*/
